use std::io::{self, ErrorKind, Read, Write};
use std::net::TcpStream;
use std::sync::mpsc::{self, TryRecvError};
use std::thread;
use std::time::Duration;

const LOCAL: &str = "127.0.0.1:8888";
const MSG_SIZE: usize = 1024;

fn main() {
  let mut client = TcpStream::connect(LOCAL).expect("无法绑定流数据");
  client
    .set_nonblocking(true)
    .expect("初始化 non-blocking 失败");

  let (tx, rx) = mpsc::channel::<String>();

  thread::spawn(move || loop {
    let mut buff = vec![0; MSG_SIZE];
    match client.read_exact(&mut buff) {
      Ok(_) => {
        let msg = buff.into_iter().take_while(|&x| x != 0).collect::<Vec<_>>();
        println!("发送的数据 byte: {:?}", msg);
      }
      Err(ref err) if err.kind() == ErrorKind::WouldBlock => (),
      Err(_) => {
        println!("~~~~~~~~~");
        break;
      }
    };

    match rx.try_recv() {
      Ok(msg) => {
        let mut buff = msg.clone().into_bytes();
        buff.resize(MSG_SIZE, 0);
        client.write_all(&buff).expect("往 socket 写入数据失败");
        println!("输入的数据： {:?}", msg);
      }
      Err(TryRecvError::Empty) => (),
      Err(TryRecvError::Disconnected) => break,
    };
    thread::sleep(Duration::from_millis(100));
  });

  print!("请输入: ");

  loop {
    let mut buff = String::new();
    io::stdin()
      .read_line(&mut buff)
      .expect("从 stdin 读取数据失败");

    let msg = buff.trim().to_string();

    // quit 退出
    if msg == "quit" || tx.send(msg).is_err() {
      break;
    };
  }

  println!("See you!");
}
